package com.rpc.server;

import com.rpc.demo.SpringContext;
import com.rpc.protocol.RpcDecode;
import com.rpc.protocol.RpcEncode;
import com.rpc.tagparser.bean.ServiceConfigBean;
import com.rpc.transport.RequestData;
import com.rpc.transport.ResponseData;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.*;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author yangzhuoleo
 * @Description ${Description}
 * @create 2017-12-31 23:39
 **/
@ToString
public class NettyServer {
    @Getter
    @Setter
    @NonNull
    private String ip;

    @Getter
    @Setter
    @NonNull
    private int port;

    @Autowired
    ServiceConfigBean serviceConfigBean;


    private EventLoopGroup boss;
    private EventLoopGroup worker;

    public NettyServer(String ip, int port) {
        this.ip = ip;
        this.port = port;
        this.boss = new NioEventLoopGroup();
        this.worker = new NioEventLoopGroup();
    }


    public void init() {
        //boss线程监听端口，worker线程负责数据读写
        ServiceConfigBean serviceConfigBean = SpringContext.getBean("testService");

        System.out.println(serviceConfigBean);
        try {
            //辅助启动类
            ServerBootstrap bootstrap = new ServerBootstrap();
            //设置线程池
            bootstrap.group(boss, worker);

            //设置socket工厂
            bootstrap.channel(NioServerSocketChannel.class);

            //设置管道工厂
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) {
                    //获取管道
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    //字符串解码器 有先后顺序
                    pipeline.addLast(new RpcDecode(RequestData.class));
                    //字符串编码器
                    pipeline.addLast(new RpcEncode(ResponseData.class));
                    //处理类
                    pipeline.addLast(new ServerHandler());
                }
            });

            //设置TCP参数
            //1.链接缓冲池的大小（ServerSocketChannel的设置）
            bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
            //维持链接的活跃，清除死链接(SocketChannel的设置)
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            //关闭延迟发送
            bootstrap.childOption(ChannelOption.TCP_NODELAY, true);

            //绑定端口
            ChannelFuture future = bootstrap.bind(this.ip, port).sync();
            //等待服务端监听端口关闭
            future.channel().closeFuture().sync();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //优雅退出，释放线程池资源
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    public void close() {
        this.worker.shutdownGracefully();
        this.boss.shutdownGracefully();
    }

    public static void main(String[] args) {

    }

}

